#include "xheader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

XSIPHeader::XSIPHeader()
{
	memset(m_header, 0, sizeof(m_header));
	for (int i = 0; i < sizeof(m_header)/sizeof(header); i ++)
	{
		m_header[i].cmd = i;
	}
}

XSIPHeader::~XSIPHeader()
{
	
}

void XSIPHeader::copy(XSIPHeader* src, int i)
{
	XSIPHeader::header *h = src->getHeader(i);
	if (h == NULL)
		return;
	addHeader(i, h->data, h->size);
}

int XSIPHeader::getHeaderSize()
{
	int size = 0;
	for (int i = 0; i < sizeof(m_header)/sizeof(header); i ++)
	{
		header* h = &m_header[i];
		if (h->size > 0)
		{
			size += h->size + sizeof(uint16_t)*2;
		}
	}
	return size;
}

bool XSIPHeader::serializeToArray(void* byte, int size)
{
	if (getHeaderSize() > size)
	{
		return false;
	}
	char* data = (char*)byte;
	for (int i = 0; i < sizeof(m_header)/sizeof(header); i ++)
	{
		header* h = &m_header[i];
		if (h->size > 0)
		{
			uint16_t *ptr = (uint16_t*)data;
			*ptr = h->cmd;
			ptr = (uint16_t*)(data + sizeof(uint16_t));
			*ptr = h->size;
			memcpy(data + sizeof(uint16_t)*2, h->data, h->size);
			data = data + sizeof(uint16_t)*2 + h->size;
		}
	}
	return true;
}

bool XSIPHeader::parseFromArray(void* byte, int size)
{
	char* data = (char*) byte;
	while(1)
	{
		uint16_t* cmd = (uint16_t*) data;
		uint16_t* len = (uint16_t*) (data + sizeof(uint16_t));
		char* val = data + sizeof(uint16_t)*2;
		addHeader(*cmd, val, *len);
		data = data + sizeof(uint16_t)*2 + *len;
		if (data[0] == '\r' && data[1] == '\n' && data[2] == '\r'
				&& data[3] == '\n')
			break;
	}
	return true;
}

XSIPHeader::header* XSIPHeader::getHeader(int i)
{
	header *h = &m_header[i];
	if (h->size <= 0)
		return NULL;
	return h;
}
	
void XSIPHeader::addHeader(int i, char* value)
{
	header *h = &m_header[i];
	sprintf(h->data, "%s", value);
	h->size = strlen(h->data) + 1;
}

void XSIPHeader::addHeader(int i, int v)
{
	header *h = &m_header[i];
	sprintf(h->data, "%d", v);
	h->size = strlen(h->data) + 1;
}

void XSIPHeader::addHeader(int i, void* val, int size)
{
	header *h = &m_header[i];
	memcpy(h->data, val, size);
	h->size = size;
}

void XSIPHeader::clearHeader(int i)
{
	header *h = &m_header[i];
	h->data[0] = '\0';
	h->size = 0;
}